package com.aispeech.task.api.handler;

import com.aispeech.data.pojo.task.Task;
import com.aispeech.task.api.data.form.NewTaskForm;
import com.aispeech.task.api.data.form.TaskForm;
import com.aispeech.task.api.data.vo.Result;
import com.aispeech.task.api.data.vo.TaskProgress;
import com.aispeech.task.api.service.ITaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

@Component
@Slf4j
public class TaskHandler {
    @Autowired
    ITaskService taskService;

    public Mono<ServerResponse> create(ServerRequest request) {
        Mono<MultiValueMap<String, String>> monoFormData = request.formData();

        Mono<Result<TaskProgress>> mono = monoFormData
                .map(multimap -> NewTaskForm.fromMap(multimap.toSingleValueMap()))
                .flatMap(taskService::newTask)
                .map(taskInfo -> Result.ok(taskInfo))
                .doOnError(throwable -> Result.throwable(throwable));

        return ServerResponse
                .ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(mono, Result.class);
    }

    public Mono<ServerResponse> progress(ServerRequest request) {
        Mono<MultiValueMap<String, String>> monoFormData = request.formData();

        Mono<Result<TaskProgress>> mono = monoFormData
                .map(multimap -> TaskForm.fromMap(multimap.toSingleValueMap()))
                .flatMap(taskService::progress)
                .map(progress -> Result.ok(progress))
                .doOnError(throwable -> Result.throwable(throwable));

        return ServerResponse
                .ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(mono, Result.class);
    }

    public Mono<ServerResponse> result(ServerRequest request) {
        Mono<MultiValueMap<String, String>> monoFormData = request.formData();

        Mono<Result<Task>> mono = monoFormData
                .map(multimap -> TaskForm.fromMap(multimap.toSingleValueMap()))
                .flatMap(taskService::result)
                .map(task -> Result.ok(task))
                .doOnError(throwable -> Result.throwable(throwable));

        return ServerResponse
                .ok()
                .contentType(MediaType.APPLICATION_JSON)
                .body(mono, Result.class);
    }
}
